'use strict';

/**
 * @author Dr_Sun
 * @name gulpfile.babel.js
 * @description
 * gulp 使用es6编译风格, 所以需要将gulpfile.scripts 更改名字为gulp.babel.scripts 同时在对应目录增加 ..babelrc
 * 整合gulp的一些插件, 编译项目
 *
 */

// This gulpfile makes use of new JavaScript features.
// Babel handles this without us having to do anything. It just works.
// You can read more about the new JavaScript features here:
// https://babeljs.io/docs/learn-es2015/

const gulp = require('gulp');
const del = require('del'); //删除文件
const runSequence = require('run-sequence');//按顺序执行
const gulpLoadPlugins = require('gulp-load-plugins'); //加载gulp-load-plugins插件，并马上运行它
const spritesmith = require('gulp.spritesmith');
const minimist = require('minimist');
const fileinclude = require('gulp-file-include');
// const imageDimensions = require('gulp-styles-image-dimensions');

const $p = gulpLoadPlugins();
const reload = $p.connect.reload;

// 错误处理
const handleErrors = function () {
  const args = Array.prototype.slice.call(arguments);
  $p.notify.onError({
    title: 'babel error',
    message: '<%=error.message %>'
  }).apply(this, args);// 替换为当前对象
  this.emit();// 提交
};

// 清除工作空间
gulp.task('clean', () => del(['tmp', '.sass-cache', 'dist']));
gulp.task('remove:tmp', () => del(['tmp']));

// copy bower_components scripts 到./tmp目录下
gulp.task('copy-bower-scripts', () => {
  gulp.src(['bower_components/*'], {dot: true}).pipe(gulp.dest('tmp/bower_components'))
    .pipe($p.size({title: 'copy'}));
});

// 静态服务器连接
gulp.task('connect', () => {
  $p.connect.server({
    root: ['src', 'tmp'],
    port: 8003,
    livereload: {
      port: 35751
    },
    host: '0.0.0.0',
    middleware: (connect) => {
      return [
        connect.static('tmp'),
        connect().use(
          '/bower_components',
          connect.static('./bower_components')
        ),
        connect.static('src')
      ];
    }
  });
  gulp.watch(['src/**/*.html'], ['reload:html']);
  gulp.watch(['src/styles/**/*.{scss,styles}'], ['image-dimensions:test', 'reload:sass']);
  gulp.watch(['src/scripts/**/*.js'], ['eslint', 'scripts', 'reload:scripts']);
  // gulp.watch(['src/images/**/*'], ['sprite', 'reload:images']);
});

// 关闭服务器
// gulp.task('jenkins-tests', function() {
//     connect.server({
//         port: 8003
//     });
//     // run some headless tests with phantomjs
//     // when process exits:
//     ;
// });
// connect.serverClose()

// 监听html
gulp.task('reload:html', () => {
  gulp.src(['src/*.html']).pipe(reload());
});

// 监听样式
gulp.task('reload:sass', function () {
  gulp.src(['src/styles/**/*']).pipe(reload());
});

// 监听图片
gulp.task('reload:images', function () {
  gulp.src(['src/images/**/*']).pipe(reload());
});

// 监听js
gulp.task('reload:scripts', function () {
  gulp.src(['src/scripts/**/*']).pipe(reload());
});

// eslintrc 检查
gulp.task('eslint', () =>
  gulp.src('src/scripts/**/*.js')
    .pipe($p.eslint())
    .pipe($p.eslint.format())
);

// 编辑雪碧图1x和2x
// gulp.task('sprite', () => {
//   /**
//    * @link https://muffinresearch.co.uk/removing-leading-whitespace-in-es6-template-strings/
//    * @return {string}
//    */
//   function L (strings) {
//     var values = Array.prototype.slice.call(arguments, 1);
//     var output = [];
//     for (var i = 0; i < values.length; i++) {
//       output.push(strings[i] + values[i]);
//     }
//
//     output.push(strings[values.length]);
//
//     var lines = output.join('').split('\n');
//     if (lines[0] === '.') {
//       lines.shift();
//     }
//
//     return lines.map(function (line) {
//       return line.replace(/^\s*\. |/gm, '');
//     }).join('\n');
//   }
//
// // 雪碧图生成合并
//   const spriteImgs = {
//     'icons': 'src/images/icons/*.png',
//     'icons-2x': 'src/images/icons-2x/*.png'
//   };
//   const spriteData = gulp.src(spriteImgs['icons']) // source path of the sprite images
//     .pipe(spritesmith({
//       imgName: 'icons.png',
//       cssName: '_icons-1x.scss',
//       cssFormat: 'scss',
//       cssTemplate: function (data) {
//         const arr = [];
//         arr.push(L`.icon {
//           .   background-repeat: no-repeat;
//           .   overflow: hidden;
//           .   display: inline-block;
//           . }\n \n`);
//
//         data.sprites.forEach(function (sprite) {
//           arr.push(L`.icon_${sprite.name} {
//           .   background-image: url('../images/${sprite.escaped_image}');
//           .   background-position: ${sprite.px.offset_x} ${sprite.px.offset_y};
//           .   background-size: ${sprite.total_width}px ${sprite.total_height}px;
//           .   width: ${sprite.px.width};
//           .   height: ${sprite.px.height};
//           . }\n \n`);
//         });
//         return arr.join('');
//       }
//     }));
//   spriteData.img.pipe(gulp.dest('tmp/images')); // output path for the sprite
//   spriteData.styles.pipe(gulp.dest('tmp/styles')); // output path for the CSS
//
//   const spriteData2 = gulp.src(spriteImgs['icons-2x'])
//     .pipe(spritesmith({
//       imgName: 'icons-2x.png',
//       cssName: '_icons-2x.scss',
//       cssFormat: 'scss',
//       cssTemplate: function (data) {
//         const arr = [];
//         data.sprites.forEach(function (sprite) {
//           arr.push(L`.icon_${sprite.name} {
//           .   @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
//           .     background-image: url('../images/${sprite.escaped_image}');
//           .     background-position: ${sprite.offset_x / 2}px ${sprite.offset_y / 2}px;
//           .     background-size: ${sprite.total_width / 2}px ${sprite.total_height / 2}px;
//           .     width: ${sprite.width / 2}px;
//           .     height: ${sprite.height / 2}px;
//           .   }
//           . }\n \n`);
//         });
//         return arr.join('');
//       }
//     }));
//   spriteData2.img.pipe(gulp.dest('tmp/images')); // output path for the sprite
//   spriteData2.styles.pipe(gulp.dest('tmp/styles')); // output path for the CSS
// });
// 雪碧图合并完成

// 将sass编辑成css
gulp.task('sass', () => {
  // For best performance, don't add Sass partials to `gulp.src`
  return gulp.src([
    'src/styles/**/*.scss',
    'tmp/styles/**/*.scss'
  ]).pipe($p.sourcemaps.init())
    .pipe($p.sass({precision: 10}))
    .on('error', $p.sass.logError)
    .pipe($p.pxtorem({
      //假设设计稿是750
      rootValue: 100, // 按照高适配，一屏展示   说是对根元素大小进行设置
      unitPrecision: 2, //转换成rem后保留的小数点位数。。。
      // propList: ['*'],假设需要仅对边框进行设置，可以写['*', '!border*']意思是排除带有border的属性，
      propWhiteList: [],
      selectorBlackList: [], //是一个对css选择器进行过滤的数组，比如你设置为['fs']，那例如fs-xl类名，里面有关px的样式将不被转换，这里也支持正则写法
      replace: true,
      mediaQuery: false,
      minPixelValue: 0 //我设置了12，意思是所有小于12px的样式都不被转换
    }))
    .pipe($p.sourcemaps.write())
    .pipe(gulp.dest('tmp/styles/'));
});

// 将less编辑成css
gulp.task('less', () => {
  return gulp.src([
    'src/style/**/*.less',
    'tmp/style/**/*.less'
  ]).pipe($p.less())
    .pipe(gulp.dest('tmp/style/'));
});



gulp.task('image-dimensions', () => {
  // For best performance, don't add Sass partials to `gulp.src`
  return gulp.src('tmp/styles/*.css')
  // .pipe(imageDimensions('../no-sprite-icons'))
  // .pipe(imageDimensions('../no-sprite-icons-2x'))
    .pipe(gulp.dest('tmp/styles/'));
});
gulp.task('image-dimensions:test', () => {
  runSequence(
    'sass',
    'image-dimensions'
  );
});

const AUTOPREFIXER_BROWSERS = [ // css3自动补全功能 //但这样的不能补全：display: flex;
  'ie_mob >= 10',
  'ff >= 30',
  'chrome >= 34',
  'safari >= 7',
  'opera >= 23',
  'ios >= 6',
  'android >= 2.0',
  'bb >= 10'
];

// 合并css
// gulp.task('concat:styles', () => {
//   // For best performance, don't add Sass partials to `gulp.src`
//   return gulp.src([
//     'tmp/styles/*.styles'
//   ]).pipe($p.concat('index.scss')).pipe(gulp.dest('tmp/styles'));
// });

gulp.task('cssmin', () => {
  // For best performance, don't add Sass partials to `gulp.src`
  return gulp.src([
    'tmp/styles/**/*.css'
  ]).pipe($p.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe($p.if('*.css', $p.cssnano()))
    .pipe($p.size({title: 'styles'}))
    .pipe($p.sourcemaps.write('./'))
    .pipe(gulp.dest('tmp/styles'));
});

// 线上scripts打包
gulp.task('scripts:dist', () =>
  gulp.src([
    // Note: Since we are not using useref in the scripts build pipeline,
    //       you need to explicitly list your scripts here in the right order
    //       to be correctly concatenated
    'src/scripts/**/*.js'
    // Other scripts
  ])
    .pipe($p.babel())
    .pipe($p.uglify())
    // Output files
    .pipe($p.size({title: 'scripts'}))
    .pipe(gulp.dest('tmp/scripts'))
);

// 本地调试scripts编译
gulp.task('scripts', () =>
  gulp.src([
    // Note: Since we are not using useref in the scripts build pipeline,
    //       you need to explicitly list your scripts here in the right order
    //       to be correctly concatenated
    'src/scripts/**/*.js'
    // 'app_public/scripts/**/*.scripts'
    // Other scripts
  ])
    .pipe($p.newer('tmp/scripts'))
    .pipe($p.sourcemaps.init())
    .pipe($p.babel())
    .on('error', handleErrors) // 交给notify处理错误
    .pipe($p.sourcemaps.write())
    .pipe(gulp.dest('tmp/scripts'))
);

// 线上html处理
gulp.task('html', () => {
  return gulp.src('src/*.html')
    .pipe(fileinclude({ // 先进行静态html嵌套
      prefix: '@@',
      basepath: '@file'
    }))
    .pipe($p.useref({searchPath: '{tmp,src}'}))
    // Minify any HTML
    .pipe($p.if('*.html', $p.htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeAttributeQuotes: true,
      removeRedundantAttributes: true,
      removeEmptyAttributes: true,
      removeScriptTypeAttributes: true,
      removeStyleLinkTypeAttributes: true,
      removeOptionalTags: true
    })))
    // Output files
    .pipe($p.if('*.html', $p.size({title: 'html', showFiles: true})))
    .pipe(gulp.dest('tmp'));
});

// 图片压缩
gulp.task('imagemin', () =>
  gulp.src(['tmp/images/**/*', 'src/images/**/*'])
    .pipe($p.cache($p.imagemin({
      optimizationLevel: 1, //类型：Number  默认：3  取值范围：0-7（优化等级
      progressive: true, //false无损压缩jpg图片
      interlaced: true //false 隔行扫描gif进行渲染
    })))
    .pipe(gulp.dest('tmp/images'))
    .pipe($p.size({title: 'images'}))
);

// 编译md5
gulp.task('md5', function () {
  return gulp.src([
    'tmp/styles/**/*.css',
    'tmp/scripts/**/*.js',
    // 'tmp/*.html',
    'tmp/images/**/*'
  ])
    .pipe($p.rev())
    .pipe(gulp.dest('tmp/md5/'))
    .pipe($p.rev.manifest())
    .pipe(gulp.dest('tmp/md5/'));
});

// 命令参数
const options = minimist(process.argv.slice(2), {});

const cdnlinks = {
  test: 'https:',
  stage: 'https:',
  dist: '',
  nocdn: ''
};
const cdnLink = (() => cdnlinks[options['_'].toString()]
)();

const md5ReLib = () => {
  return gulp.src([
    'cdn.json',
    'tmp/*.html'
  ]).pipe($p.revCollector({
    replaceReved: false,
    dirReplacements: {
      'libs/': `${cdnLink}libs`
    }
  })).pipe($p.if('*.html', gulp.dest('dist')));
};
// 替换index里面引用的link和src
const md5ReHtmlSrcAndLink = () => {
  return gulp.src([
    'tmp/md5/*.json',
    'tmp/*.html'
  ]).pipe($p.revCollector({
    replaceReved: true,
    dirReplacements: {
      'styles': `${cdnLink}styles`,
      'scripts': `${cdnLink}scripts`
    }
  })).pipe($p.if('*.html', gulp.dest('tmp')));
  return gulp.src([
    'tmp/*.json',
    'tmp/*.html'
  ]).pipe($p.revCollector({
    replaceReved: true,
    dirReplacements: {
      'styles': `${cdnLink}styles`,
      'scripts': `${cdnLink}scripts`
    }
  })).pipe($p.if('*.html', gulp.dest('tmp')));
};
// 替换文件内部引用的html png scripts styles
const md5Re = () => {
  return gulp.src([
    'tmp/*.json',
    'tmp/md5/**/*.css',
    'tmp/**/*.html',
    'tmp/**/*.png',
    'tmp/**/*.jpeg',
    'tmp/md5/**/*.js',
    'tmp/*.html'
  ]).pipe($p.revCollector()).pipe($p.if('**/*.css', gulp.dest('dist/styles')))
  // .pipe($p.if('**/*.html', gulp.dest('dist/views')))
    .pipe($p.if('**/*.js', gulp.dest('dist/scripts'))).pipe($p.if('*.html', gulp.dest('dist')));
};

gulp.task('md5replacelib', ['md5replace2'], function () {
  return md5ReLib();
});
gulp.task('md5replace2', ['md5replace'], function () {
  return md5ReHtmlSrcAndLink();
});
// 资源cdn替换
gulp.task('md5replace', function () {
  return md5Re();
});

// 移动文件
gulp.task('mv:files', () => {
  // gulp.src(['tmp/fonts/*']).pipe(gulp.dest('tmp/fonts/'));
// 移动不需要编译的文件
  gulp.src(['src/images/*']).pipe(gulp.dest('dist/images/'));
  gulp.src(['src/favicon.ico', 'src/hack.gif']).pipe(gulp.dest('dist'));
  gulp.src(['src/libs/*']).pipe(gulp.dest('dist/libs/'));
  gulp.src(['src/fonts/*']).pipe(gulp.dest('dist/fonts/'));
  gulp.src(['src/styles/*.css']).pipe(gulp.dest('dist/styles/'));
    gulp.src(['src/include/*.html']).pipe(gulp.dest('dist/include/'));
    gulp.src(['src/media/*']).pipe(gulp.dest('dist/media/'));
});

gulp.task('cdn', ['md5replacelib']);

gulp.task('serve', () => {
  runSequence(
    'clean',
    // 'imagemin',
    'eslint',
    'sass',
    'less',
    // 'image-dimensions',
    'scripts',
    // 'copy-bower-scripts',
    'connect'
  );
});

gulp.task('dist', () => {
  runSequence(
    'clean',
    // 'imagemin',
    'sass',
    'less',
    'html',
    // 'image-dimensions',
    'cssmin',
    'scripts:dist',
    'md5',
    'cdn',
    'mv:files',
    'remove:tmp'
  );
});

gulp.task('nocdn', () => {
  runSequence(
    'clean',
    'imagemin',
    'sass',
    'html',
    'image-dimensions',
    'cssmin',
    'scripts:dist',
    'md5',
    'cdn',
    'mv:files'
  );
});
